package org.linlinjava.litemall.admin.service;


import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.linlinjava.litemall.admin.vo.CatVo;
import org.linlinjava.litemall.core.qcode.QCodeService;
import org.linlinjava.litemall.core.util.ResponseUtil;
import org.linlinjava.litemall.db.dao.LitemallGoodsMapper;
import org.linlinjava.litemall.db.dao.LitemallGoodsProductMapper;
import org.linlinjava.litemall.db.domain.*;
import org.linlinjava.litemall.db.domain.vo.LitemallGoodsDto;
import org.linlinjava.litemall.db.service.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static org.linlinjava.litemall.admin.util.AdminResponseCode.GOODS_NAME_EXIST;

@Service
public class AdminGoodsService {
    private final Log logger = LogFactory.getLog(AdminGoodsService.class);

    @Autowired
    private LitemallBookReviewService bookReviewService;
    @Autowired
    private LitemallGoodsService goodsService;
    @Autowired
    private LitemallGoodsSpecificationService specificationService;
    @Autowired
    private LitemallGoodsAttributeService attributeService;
    @Autowired
    private LitemallGoodsProductService productService;

    @Autowired
    private LitemallCategoryService categoryService;
    @Autowired
    private LitemallBrandService brandService;
    @Autowired
    private LitemallCartService cartService;
    @Autowired
    private QCodeService qCodeService;
    @Autowired
    private LitemallMemberRuleService memberRuleService;
    @Autowired
    private LitemallGoodsMapper goodsMapper;
    @Autowired
    private LitemallGoodsProductMapper productMapper;
    @Autowired
    private AdminArrivalReminderService adminArrivalReminderService;
    @Autowired
    private LitemallArrivalReminderService arrivalReminderService;

    public List<LitemallGoods> list(Integer goodsId, String goodsSn, String name, String author,
                                    Integer page, Integer limit, String sort, String order) {
        List<LitemallGoods> goodsList = goodsService.querySelective(goodsId, goodsSn, name, author, page, limit, sort, order);



        for (LitemallGoods goods : goodsList) {

            List<LitemallGoodsProduct> products = productMapper.
                    selectList(Wrappers.<LitemallGoodsProduct>lambdaQuery().eq(LitemallGoodsProduct::getGoodsId, goods.getId()));
            LitemallGoodsProduct product = new LitemallGoodsProduct();
            if (ObjectUtil.isNotEmpty(products)) {
                Integer count = products.stream().mapToInt(LitemallGoodsProduct::getNumber).sum();
                product = products.get(0);
                product.setNumber(count);
            }
            goods.setInventory(product);
        }
        return goodsList;
    }

    public Object exportExcel(Integer goodsId, String goodsSn, String name, String author,
                              Integer page, Integer limit, String sort, String order) {
        List<LitemallGoods> goodsList = goodsService.querySelective(goodsId, goodsSn, name, author, page, limit, sort, order);

        return ResponseUtil.okList(goodsList);
    }

    private Object validate(LitemallGoodsDto dto) {

        LitemallGoods goods = new LitemallGoods();
        BeanUtils.copyProperties(dto, goods);

//
//        String goodsSn = goods.getGoodsSn();
//        if (StringUtils.isEmpty(goodsSn)) {
//            return ResponseUtil.fail(400, "商品sn不能为空");
//        }

        if (goods.getBookDigit() < 1 || goods.getBookDigit() > 9) {
            return ResponseUtil.fail(400, "数位数量只能为1-9之间数字");
        }
        // 品牌商可以不设置，如果设置则需要验证品牌商存在
//        Integer brandId = goods.getBrandId();
//        if (brandId != null && brandId != 0) {

        if (ObjectUtil.isNotEmpty(goods.getBrandId())&&goods.getBrandId()!=0) {
            if (brandService.findById(goods.getBrandId()) == null) {
                return ResponseUtil.badArgumentValue();
            }
        }
//        }
        // 分类可以不设置，如果设置则需要验证分类存在
//        Integer categoryId = goods.getCategoryId();
//        if (categoryId != null && categoryId != 0) {
        if (categoryService.findById(goods.getCategoryId()) == null) {
            return ResponseUtil.fail(400, "分类不存在");
        }
//        }

//        LitemallGoodsSpecification[] specifications = goodsAllinone.getSpecifications();
//        LitemallGoodsSpecification specifications = goodsAllinone.getSpecifications();
//        for (LitemallGoodsSpecification specification : specifications) {
//            String spec = specification.getSpecification();
//            if (StringUtils.isEmpty(spec)) {
//                return ResponseUtil.fail(400, "分类不能为空");
//            }
//            String value = specification.getValue();
//            if (StringUtils.isEmpty(value)) {
//                return ResponseUtil.fail(400, "分类不能为空");
//            }
//        }

        LitemallGoodsProduct product = dto.getInventory();
//        for (LitemallGoodsProduct product : products) {
        Integer number = product.getNumber();
        if (number == null || number < 0) {
            return ResponseUtil.fail(400, "数量不能小于0");
        }

        BigDecimal price = product.getPrice();
        if (price == null) {
            return ResponseUtil.fail(400, "商品价格不能为空");
        }

        BigDecimal memberPrice = product.getMemberPrice();
        if (!number.equals(0) && memberPrice == null) {
            return ResponseUtil.fail(400, "商品会员价不能为空");
        }

        String productSpecifications = product.getSpecifications();
        if (productSpecifications == null) {
            return ResponseUtil.fail(400, "商品分类不能为空");
        }
//        }

        return null;
    }

    /**
     * 编辑商品
     * <p>
     * NOTE：
     * 由于商品涉及到四个表，特别是litemall_goods_product表依赖litemall_goods_specification表，
     * 这导致允许所有字段都是可编辑会带来一些问题，因此这里商品编辑功能是受限制：
     * （1）litemall_goods表可以编辑字段；
     * （2）litemall_goods_specification表只能编辑pic_url字段，其他操作不支持；
     * （3）litemall_goods_product表只能编辑price, number和url字段，其他操作不支持；
     * （4）litemall_goods_attribute表支持编辑、添加和删除操作。
     * <p>
     * NOTE2:
     * 前后端这里使用了一个小技巧：
     * 如果前端传来的update_time字段是空，则说明前端已经更新了某个记录，则这个记录会更新；
     * 否则说明这个记录没有编辑过，无需更新该记录。
     * <p>
     * NOTE3:
     * （1）购物车缓存了一些商品信息，因此需要及时更新。
     * 目前这些字段是goods_sn, goods_name, price, pic_url。
     * （2）但是订单里面的商品信息则是不会更新。
     * 如果订单是未支付订单，此时仍然以旧的价格支付。
     */
    @Transactional(rollbackFor = Exception.class)
    public Object update(LitemallGoodsDto dto) {
        Object error = validate(dto);
        if (error != null) {
            return error;
        }

        LitemallGoods goods = new  LitemallGoods();
        BeanUtils.copyProperties(dto, goods);
//        LitemallGoodsSpecification[] specifications = goodsAllinone.getSpecifications();
//        LitemallGoodsProduct[] products = goodsAllinone.getProducts();
        LitemallGoodsProduct product =dto.getInventory();

        /* 商品表里面有一个字段retailPrice记录当前商品的最高价,memberPrice记录当前商品会员价的最高价 */
        BigDecimal retailPrice = BigDecimal.ZERO;
        BigDecimal memberPrice = BigDecimal.ZERO;
//        for (LitemallGoodsProduct product : products) {
        BigDecimal productPrice = product.getPrice();
        BigDecimal productMemberPrice = product.getMemberPrice();
        if (retailPrice.compareTo(productPrice) < 0) {
            retailPrice = productPrice;
        }
        if (memberPrice.compareTo(productMemberPrice) < 0) {
            memberPrice = productMemberPrice;
        }
//        }
        goods.setRetailPrice(retailPrice);
        goods.setMemberPrice(memberPrice);

        // 商品基本信息表litemall_goods
        if (goodsService.updateById(goods) == 0) {
            throw new RuntimeException("更新数据失败");
        }

        Integer gid = goods.getId();

        // 商品规格表litemall_goods_specification
//        for (LitemallGoodsSpecification specification : specifications) {
//            // 目前只支持更新规格表的图片字段
//            if (specification.getUpdateTime() == null) {
//                specification.setSpecification(null);
//                specification.setValue(null);
//                specificationService.updateById(specification);
//            }
//        }

        // 商品货品表litemall_product
//        for (LitemallGoodsProduct product : products) {
        if (product.getId() == null && product.getNumber().equals(0)) {
//                continue;
        } else if (product.getId() == null && product.getNumber() > 0) {
            product.setGoodsId(goods.getId());
            productService.add(product);
        } else {
            productService.updateById(product);
        }
        // 这里需要注意的是购物车litemall_cart有些字段是拷贝商品的一些字段，因此需要及时更新
        // 目前这些字段是goods_sn, goods_name, price,memberPrice, pic_url
        cartService.updateProduct(product.getId(), goods.getGoodsSn(), goods.getName(), product.getPrice(), product.getMemberPrice(), product.getUrl());

        // 到货提醒
        List<LitemallArrivalReminder> arrivalReminderList = arrivalReminderService.queryByProductId(product.getId());
        if (!arrivalReminderList.isEmpty()) {
            for (LitemallArrivalReminder arrivalReminder : arrivalReminderList) {
                adminArrivalReminderService.sendArrivalRemind(arrivalReminder);
            }
        }
//        }
        return ResponseUtil.ok();
    }

    @Transactional
    public Object delete(LitemallGoods goods) {
        Integer id = goods.getId();
        if (id == null) {
            return ResponseUtil.badArgument();
        }

        Integer gid = goods.getId();
        goodsService.deleteById(gid);
        specificationService.deleteByGid(gid);
        attributeService.deleteByGid(gid);
        productService.deleteByGid(gid);
        productService.queryByGid(gid).forEach(product -> bookReviewService.deleteById(product.getId()));
        return ResponseUtil.ok();
    }

    @Transactional(rollbackFor = Exception.class)
    public Object create(LitemallGoodsDto dto) {
        Object error = validate(dto);
        if (error != null) {
            return error;
        }

        // todo 校验书位

        LitemallGoods goods = new LitemallGoods();

        BeanUtils.copyProperties(dto, goods);
        if (StringUtils.isEmpty(goods.getAuthor())) {
            goods.setAuthor("");
        }

//        LitemallGoodsSpecification[] specifications = goodsAllinone.getSpecifications();
//        LitemallGoodsProduct[] products = goodsAllinone.getProducts();
        LitemallGoodsProduct product = dto.getInventory();

        String name = goods.getName();
        if (goodsService.checkExistByName(name)) {
            return ResponseUtil.fail(GOODS_NAME_EXIST, "商品名已经存在");
        }




        /* 商品表里面有一个字段retailPrice记录当前商品的最高价,memberPrice记录当前商品会员价的最高价 */
        BigDecimal retailPrice = BigDecimal.ZERO;
        BigDecimal memberPrice = BigDecimal.ZERO;
//        for (LitemallGoodsProduct product : products) {
        BigDecimal productPrice = product.getPrice();
        BigDecimal productMemberPrice = product.getMemberPrice();
        if (retailPrice.compareTo(productPrice) < 0) {
            retailPrice = productPrice;
        }
        if (memberPrice.compareTo(productMemberPrice == null ? BigDecimal.ZERO : productMemberPrice) < 0) {
            memberPrice = productMemberPrice;
        }
//        }
        goods.setRetailPrice(retailPrice);
        goods.setMemberPrice(memberPrice);

        // 商品基本信息表litemall_goods
        goodsService.add(goods);

        // 商品规格表litemall_goods_specification
//        for (LitemallGoodsSpecification specification : specifications) {
//            specification.setGoodsId(goods.getId());
//            specificationService.add(specification);
//        }

        // 商品货品表litemall_product
//        for (LitemallGoodsProduct product : products) {
        if (product.getNumber() > 0) {
            product.setGoodsId(goods.getId());
            productService.add(product);
        }
//        }
        return ResponseUtil.ok();
    }

    public Object list2() {
        // http://element-cn.eleme.io/#/zh-CN/component/cascader
        // 管理员设置“所属分类”
        List<LitemallCategory> l1CatList = categoryService.queryL1();
        List<CatVo> categoryList = new ArrayList<>(l1CatList.size());

        for (LitemallCategory l1 : l1CatList) {
            CatVo l1CatVo = new CatVo();
            l1CatVo.setValue(l1.getId());
            l1CatVo.setLabel(l1.getName());
            l1CatVo.setCanBorrow(l1.getCanBorrow());

            List<LitemallCategory> l2CatList = categoryService.queryByPid(l1.getId());
            List<CatVo> children = new ArrayList<>(l2CatList.size());
            for (LitemallCategory l2 : l2CatList) {
                CatVo l2CatVo = new CatVo();
                l2CatVo.setValue(l2.getId());
                l2CatVo.setLabel(l2.getName());
                children.add(l2CatVo);
            }
            l1CatVo.setChildren(children);

            categoryList.add(l1CatVo);
        }

        // http://element-cn.eleme.io/#/zh-CN/component/select
        // 管理员设置“所属品牌商”
        List<LitemallBrand> list = brandService.all();
        List<Map<String, Object>> brandList = new ArrayList<>(l1CatList.size());
        for (LitemallBrand brand : list) {
            Map<String, Object> b = new HashMap<>(2);
            b.put("value", brand.getId());
            b.put("label", brand.getName());
            brandList.add(b);
        }

        Map<String, Object> data = new HashMap<>();
        data.put("categoryList", categoryList);
        data.put("brandList", brandList);
        return ResponseUtil.ok(data);
    }

    public Object detail(Integer id) {
        LitemallGoods goods = goodsService.findById(id);
        List<LitemallGoodsProduct> products = productMapper.
                selectList(Wrappers.<LitemallGoodsProduct>lambdaQuery().eq(LitemallGoodsProduct::getGoodsId, goods.getId()).orderByDesc(LitemallGoodsProduct::getId));
        if (ObjectUtil.isNotEmpty(products)){
            LitemallGoodsProduct product=products.get(0);
            goods.setInventory(product);
        }
        Map<String, Object> data = new HashMap<>();
        data.put("goods", goods);
        return ResponseUtil.ok(data);
    }


    /**
     * 通过isbn码查询商品
     *
     * @param isbn13
     * @return
     */
    public Map<String, Object> queryByISBN13(String isbn13) {
        LitemallGoodsExample example = new LitemallGoodsExample();
        example.or().andIsbn13EqualTo(isbn13).andDeletedEqualTo(false);
        LitemallGoods litemallGoods = goodsMapper.selectOneByExample(example);
        if (litemallGoods == null) {
            return null;
        } else {
            Map<String, Object> map = new HashMap<>();
            List<LitemallGoodsProduct> litemallGoodsProducts = productService.queryByGid(litemallGoods.getId());
            map.put("goods", litemallGoods);
            map.put("goodsProduct", litemallGoodsProducts);
            return map;
        }
    }

    public Object queryByIsbn(String isbn13) {
        LitemallGoodsExample example = new LitemallGoodsExample();
        example.or().andIsbn13EqualTo(isbn13).andIsOnSaleEqualTo(true).andDeletedEqualTo(false);
        LitemallGoods litemallGoods = goodsMapper.selectOneByExample(example);
        if (litemallGoods == null) {
            return null;
        } else {
            return litemallGoods.getId();
        }
    }

    public Object updateIsHot(Integer goodsId) {
        LitemallGoods goods = goodsService.findById(goodsId);
        if (goods == null) {
            return ResponseUtil.fail(400, "商品不存在");
        }
        goods.setIsHot(!goods.getIsHot());
        goodsService.updateById(goods);
        return ResponseUtil.ok(goods);
    }

}
